var CryptoJS = require("crypto-js")
const adminModel = require('../model/adminModel')
const accessModel = require("../model/accessModel")
const roleModel = require("../model/roleModel")
class Admin {
	static async login(ctx) {
		// 获取用户名 密码  返回用户信息 返回token   ctx.request.body 获取post的参数
		const {
			username,
			password
		} = ctx.request.body
		console.log(username, password)
		// 非空验证
		if (!username && !password) {
			ctx.body = {
				code: 1,
				codeInfo: "用户名或密码不能为空"
			}
		} else {
			// 查数据库
			let userObj = await adminModel.doLogin(username)
			let user = userObj[0]
			if (!user) {
				ctx.body = {
					code: 2,
					codeInfo: "用户名错误"
				}
			} else {
				let psw = CryptoJS.MD5(CryptoJS.MD5(password).toString()).toString()
				// 判断我们加密的密码 是否等于 数据库的密码
				if (psw === user.password) {
					// 生成token
					let token = CryptoJS.MD5(`${user.id}-${psw}-${Date.now()}`).toString()
					// 过期时间1天
					let exp = Date.now() + 1000 * 60 * 60 * 24
					await adminModel.addToken(user.id, token, exp)
					delete user.password
					ctx.body = {
						code: 0,
						codeInfo: "登录成功",
						data: {
							token: token,
							...user
						}
					}
				} else {
					ctx.body = {
						code: 3,
						codeInfo: "密码错误"
					}
				}
			}

		}

		// ctx.body = CryptoJS.MD5(CryptoJS.MD5("123456").toString()).toString()
	}


	static async getAdminList(ctx) {
		let username = ctx.query.username || ''
		let page = ctx.query.page || 1
		let pagesize = ctx.query.pagesize || 10
		let res = await adminModel.getUser(username, page, pagesize)
		ctx.body = {
			code: 0,
			codeInfo: "成功",
			data: {
				list: res.res,
				count: res.count[0].num
			}
		}
	}

	static async addUser(ctx) {
		let username = ctx.request.body.username
		let password = ctx.request.body.password
		let nickname = ctx.request.body.nickname
		if (!username || !password || !nickname) {
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else {
			let psw = CryptoJS.MD5(CryptoJS.MD5(password).toString()).toString()
			let res = await adminModel.addUser(username, psw, nickname)
			if (res.affectedRows == 1) {
				ctx.body = {
					code: 0,
					codeInfo: "添加成功",
					data: res
				}
			} else {
				ctx.body = {
					code: 2,
					codeInfo: "添加失败"
				}
			}
		}
	}

	// 修改管理员列表
	static async editUser(ctx) {
		let {
			nickname,
			id,
			password
		} = ctx.request.body
		if (!nickname || !id || !password) {
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else {
			let psw = CryptoJS.MD5(CryptoJS.MD5(password).toString()).toString()
			await adminModel.edit(id, psw, nickname)
		}
		ctx.body = {
			code: 0,
			codeInfo: "修改成功"
		}
	}

	// 删除管理员
	static async delUser(ctx) {
		let id = ctx.request.query.id
		if (!id) {
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else {
			await adminModel.del(id)
		}
		ctx.body = {
			code: 0,
			codeInfo: "删除成功"
		}
	}

	// 获取角色列表
	static async getRoleList(ctx) {
		let res = await roleModel.getRole()
		ctx.body = {
			code: 0,
			codeInfo: "获取成功",
			data: res
		}
	}
	// 获取角色下的用户列表
	static async getRoleUserList(ctx) {
		let rid = ctx.request.query.rid
		if (!rid) {
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else {
			let res = await roleModel.getRoleUser(rid)
			ctx.body = {
				code: 0,
				codeInfo: "获取成功",
				data: res
			}
		}
	}
	// 设置用户到某个角色
	static async addUserToRole(ctx) {
		let uid = ctx.request.body.uid,
			rid = ctx.request.body.rid
		if (!uid || !rid) {
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else {
			await roleModel.addRoleUser(uid, rid)
		}
		ctx.body = {
			code: 0,
			codeInfo: "添加成功"
		}
	}
	// 将某个角色中的用户移除
	static async delUserFromRole(ctx) {
		let uid = ctx.request.query.uid,
			rid = ctx.request.query.rid
		if (!uid || !rid) {
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else {
			await roleModel.delRoleUser(uid, rid)
		}
		ctx.body = {
			code: 0,
			codeInfo: "删除成功"
		}
	}

	// 添加一个角色
	static async addRole(ctx) {
		let name = ctx.request.body.name,
			status = ctx.request.body.status
		if (!name || !status) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else { // 参数完整，进行添加操作
			await roleModel.addRole(name, status)
		}
		ctx.body = {
			code: 0,
			codeInfo: "添加成功"
		}
	}

	// 修改角色信息
	static async editRole(ctx) {
		let rid = ctx.request.body.rid,
			name = ctx.request.body.name,
			status = ctx.request.body.status
		if (!rid || !name || !status) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else { // 参数完整，进行修改操作
			await roleModel.editRole(rid, name, status)
		}
		ctx.body = {
			code: 0,
			codeInfo: "修改成功"
		}
	}

	// 删除角色
	static async delRole(ctx) {
		let rid = ctx.request.query.rid
		if (!rid) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else { // 参数完整，进行删除操作
			await roleModel.delRole(rid)
		}
		ctx.body = {
			code: 0,
			codeInfo: "删除成功"
		}
	}

	// 获取权限列表
	static async getAccessList(ctx) {
		let list = await accessModel.getAccessList()
		ctx.body = {
			code: 0,
			codeInfo: "获取成功",
			data: list
		}
	}

	// 添加权限
	static async addAccess(ctx) {
		let {
			name,
			path,
			pid,
			redirect,
			component,
			menutype,
			val,
			keepalive
		} = ctx.request.body
		if (!name || !menutype) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
		} else { // 参数完整，进行添加操作
			await accessModel.addAccess(name, path, pid, redirect, component, menutype, val, keepalive)
			ctx.body = {
				code: 0,
				codeInfo: "添加成功"
			}
		}
	}

	// 修改权限
	static async editAccess(ctx) {
		let {
			aid,
			name,
			path,
			pid,
			redirect,
			component,
			menutype,
			val,
			keepalive
		} = ctx.request.body
		if (!aid || !name || !menutype) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
			return
		} else { // 参数完整，进行修改操作
			await accessModel.edit(name, path, pid, redirect, component, menutype, val, keepalive, aid)
			ctx.body = {
				code: 0,
				codeInfo: "修改成功"
			}
		}
	}

	// 删除权限
	static async delAccess(ctx) {
		let aid = ctx.query.aid
		if (!aid) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
			return
		} else { // 参数完整，进行删除操作
			await accessModel.del(aid)
			ctx.body = {
				code: 0,
				codeInfo: "删除成功"
			}
		}
	}
	// 获取某个角色下面的权限树
	static async getRoleAccess(ctx) {
		let rid = ctx.query.rid
		if (!rid) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
			return
		} else { // 参数完整，进行删除操作
			let list = await accessModel.getRoleAccess(rid)
			ctx.body = {
				code: 0,
				codeInfo: "获取成功",
				data: list
			}
		}
	}

	// 设置某个角色的权限树  1,2,3
	static async addRoleAccess(ctx) {
		let {
			rid,
			aidArr
		} = ctx.request.body
		console.log(aidArr, 213)
		if (!rid || !aidArr) { // 检查参数是否完整
			ctx.body = {
				code: 1,
				codeInfo: "缺少必要参数"
			}
			return
		} else { // 参数完整，进行删除操作

			await accessModel.addRoleAccess(rid, aidArr)
			ctx.body = {
				code: 0,
				codeInfo: "设置成功"
			}
		}
	}

	static async getPermission(ctx) {
		let uid = await adminModel.checkToken(ctx.request.header.authorization)
		let ridArr = await roleModel.getUserRole(uid[0].uid)
		let res = []
		let rid
		if (ridArr.length === 0) {
			res = []
		} else {
			rid = ridArr[0].rid
			res = await accessModel.getRouter(rid)
		}

		/**
		 * @param {Object} data
		 * 初始化 map: 使用一个对象 map 来存储每个元素，以 aid 作为键，值为该元素的对象，并初始化 children 和 permission 数组。
构建树形结构: 遍历数据，根据 pid 来确定父子关系。如果 pid 为 0，则该元素为根节点；否则，检查 menutype，如果是 2，则将其添加到父节点的 permission 数组中；
否则，添加到 children 数组中。
返回根节点数组: 最终返回构建好的树形结构。
		 */
		function tree(data) {
			const map = {};
			const roots = [];

			// 初始化 map，将每个元素的 aid 作为 key
			data.forEach(item => {
				map[item.aid] = {
					...item,
					children: [],
					meta: {
						permission: []
					}
				};
			});
			// 构建树形结构
			data.forEach(item => {
				if (item.pid === 0) {
					// 根节点
					roots.push(map[item.aid]);
				} else {
					// 子节点
					if (map[item.pid]) {
						if (item.menutype === 2) {
							// 如果 menutype 为 2，添加到父节点的 permission 属性中
							map[item.pid].meta.permission.push(map[item.aid].val);
						} else {
							// 否则，添加到父节点的 children 属性中
							map[item.pid].children.push(map[item.aid]);
						}
					}
				}
			});

			return roots;
		}

		ctx.body = {
			code: 0,
			codeInfo: "成功",
			data: tree(res)
		}
	}
}

module.exports = Admin